-
Notifications
You must be signed in to change notification settings - Fork 494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Internal] Query: Fixes occasional hang while querying using partial partition key against a sub-partitioned container #4359
Conversation
7aae2a0
to
5d4a1a1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
200cb03
to
d23b9b7
Compare
[Nit] Please indent for readability #Resolved Refers to: Microsoft.Azure.Cosmos/src/Query/Core/Pipeline/CosmosQueryExecutionContextFactory.cs:301 in d23b9b7. [](commit_id = d23b9b7, deletion_comment = False) |
...os/src/Query/Core/Pipeline/CrossPartition/Parallel/QueryPartitionRangePageAsyncEnumerator.cs
Show resolved
Hide resolved
Regarding (3) in the description, the EPK range headers are used to indicate EPK range filtering to the backend. That, or the query itself can have a filter predicate. |
Neil - yes, I learnt about the startEpkRange and endEpkRange headers while working on this change. Do you know if the DocumentResourceContentEnumerator honors this range in the backend for Query (or something else) ? For 4, I was referring to QueryPartitionRangePageAsyncEnumerator, which uses PartitionKey field for making a decision about FeedRange. #Resolved |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...os/src/Query/Core/Pipeline/CrossPartition/Parallel/QueryPartitionRangePageAsyncEnumerator.cs
Show resolved
Hide resolved
"EffectiveRangesForPartitionKey should be populated when PK is specified in request options."); | ||
} | ||
|
||
foreach (Documents.Routing.Range<String> epkForPartitionKey in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Template
Description
This change contains the fix for occasional hang that can occur while querying using partition partition key against a sub-partitioned container. Let's assume a container with partition key definition "/id", "/value1", "/value2". Unlike single-key partition definition, for hierarchical partitions, partition splits occurs such that for a certain value of "/id" (say 2), more than one partition contains the data for this (partial) partition value. When a query is issued with partial partition key ("/id" = 2 in this case), query enumerator (QueryPartitionRangePageAsyncEnumerator L50) attempts to query a feedrange based on this partial value that isn't fully contained inside a single physical partition in the backend. Since such a range cannot be resolved to any single physical partition, enumerator receives a GoneException from the underlying stack. The GoneException is caught by upstream (CrossPartitionRangePageAsyncEnumerator L114) which attempts to resolve the physical partition ranges by consulting the routing map. This is typically a no-op since the GoneException isn't received because of a change in state of the backend.
This doesn't actually help since CrossPartitionRangePageAsyncEnumerator attempts to locate FeedRangeEpk (without the partial partition key, which honors partition boundary) inside a physical partition range - which always succeeds and further downstream (RequestInvokerHandler.ResolveFeedRangeBasedOnPrefixContainerAsync and RequestInvokerHandler L244) ignores this FeedRangeEpk and instead queries using partial partition key (FeedRangePartitionKey) which spans across the partition boundary. The later continues to cause another GoneException and cycle repeats.
This fix limits the epk range for QueryPartitionRangePageAsyncEnumerator such that it does not span across the single physical partition range. It also uses FeedRangeEpk to represent this new partition range, which causes downstream to no longer perform extraneous operations (such as ResolveFeedRangeBasedOnPrefixContainerAsync).
Several parts of the code are suspect here and a more comprehensive fix may be needed to handle all cases generally, outside this change.
Type of change
Please delete options that are not relevant.
Closing issues
To automatically close an issue: closes #4326